package generics;

/**
 * Java 泛型中的通配符 T，E，K，V，？,你确定都了解吗？
 * 泛型带来的好处
 * 泛型中通配符
 * 常用的 T，E，K，V，？
 * ？无界通配符
 * 上界通配符 < ? extends E>
 * 下界通配符 < ? super E>
 * ？和 T 的区别
 * Class<T>和 Class<?>区别
 *
 * Java 泛型（generics）是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制，
 * 该机制允许开发者在编译时检测到非法的类型。
 * 泛型的本质是参数化类型，也就是说所操作的数据类型被指定为一个参数。
 *
 * 在没有泛型的情况的下，通过对类型 Object 的引用来实现参数的“任意化”，
 * “任意化”带来的缺点是要做显式的强制类型转换，而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。
 * 对于强制类型转换错误的情况，编译器可能不提示错误，在运行的时候才出现异常，这是本身就是一个安全隐患。
 *
 * 那么泛型的好处就是在编译的时候能够检查类型安全，并且所有的强制转换都是自动和隐式的。
 * */
public class Lesson1<T> {

    private T name;

    public T getName() {
        return name;
    }

    public void setName(T name) {
        this.name = name;
    }

    public static void main(String[] args) {
        // 不指定类型，需要强制转换
        Lesson1 glmapperGeneric1 = new Lesson1();
        glmapperGeneric1.setName("张三");
        String name1 = (String) glmapperGeneric1.getName();
        System.out.println("glmapperGeneric1 : " + name1);

        //不加泛型，强制转编译器无法提示错误，在运行的时候才出现异常
        //Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
        //	at generics.GlmapperGeneric.main(GlmapperGeneric.java:44)
        //Integer nam = (Integer) glmapperGeneric1.getName();


        // 指定类型，不需要手动进行强制转换, 所有的强制转换都是自动和隐式的。由编译器完成
        Lesson1<String> glmapperGeneric2 = new Lesson1();
        glmapperGeneric2.setName("李四");
        glmapperGeneric2.getName();

        String name2 =  glmapperGeneric2.getName();
        System.out.println("glmapperGeneric2 : " + name2);
    }
}
